package com.dy.yunying.biz.controller.usergroup;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dy.yunying.api.entity.usergroup.*;
import com.dy.yunying.api.enums.UserGroupTypeEnum;
import com.dy.yunying.api.req.usergroup.UserGroupDataReq;
import com.dy.yunying.api.vo.usergroup.DeviceVo;
import com.dy.yunying.api.vo.usergroup.ProvinceCityVo;
import com.dy.yunying.api.vo.usergroup.UserGroupDataVo;
import com.dy.yunying.biz.service.datacenter.UserGroupDetailService;
import com.dy.yunying.biz.service.manage.GameService;
import com.dy.yunying.biz.service.usergroup.*;
import com.dy.yunying.biz.utils.RedisLock;
import com.pig4cloud.pig.admin.api.feign.RemoteUserService;
import com.pig4cloud.pig.api.util.NoRepeatSubmit;
import com.pig4cloud.pig.common.core.util.R;
import com.pig4cloud.pig.common.log.annotation.SysLog;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * 用户群组
 * @author zhuxm
 * @date 2022-04-25 15:11:05
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/userGroupData")
@Api(value = "userGroupData", tags = "用户管理-用户群组数据")
@Slf4j
public class UserGroupDataController {

	private final UserGroupService userGroupService;
	private final UserGroupDataService userGroupDataService;
	private final UserGroupDetailService userGroupDetailService;
	private final RemoteUserService remoteUserService;
	private final GameService gameService;

	private final DeviceInfoService deviceInfoService;

	private final DeviceService deviceService;

	private final AreaInfoService areaInfoService;

	private final ProvinceCityInfoService provinceCityInfoService;

	private final RedisLock redisLock;



	@ApiOperation(value = "用户群组数据列表", notes = "用户群组数据列表")
	@RequestMapping("/selectPage")
	public R selectPage(@Valid @RequestBody UserGroupDataReq req) {
		try {
			QueryWrapper<UserGroupData> query = new QueryWrapper<>();
			query.lambda().eq(req.getGroupId() != null, UserGroupData::getGroupId, req.getGroupId())
					.orderByDesc(UserGroupData::getCreateTime, UserGroupData::getId);
			IPage<UserGroup> iPage = userGroupDataService.page(req, query);
			return R.ok(iPage);
		} catch (Exception e) {
			log.error("用户管理-用户群组数据列表-接口：{}", e.getMessage());
			return R.failed("接口异常，请联系管理员");
		}
	}



	@ApiOperation(value = "用户群组数据统计", notes = "用户群组数据统计")
	@RequestMapping("/count")
	public R selectCount(@Valid @RequestBody UserGroupDataReq req) {
		try {
			UserGroup userGroup = userGroupService.getById(req.getGroupId());
			if (userGroup == null || userGroup.getDeleted() == 1) {
				return R.ok(0);
			}
			//筛选方式：1规则筛选，2ID筛选
			Integer type = userGroup.getType();
			switch (UserGroupTypeEnum.getOneByType(type)){
				case RULE : //规则
//					UserGroupDetailReq detailReq = new UserGroupDetailReq();
//					detailReq.setGroupId(req.getGroupId());
//					return userGroupDetailService.count(detailReq);
					return R.ok(userGroup.getUserNums());
				case ID_FILTER: //ID筛选
					QueryWrapper<UserGroupData> query = new QueryWrapper<>();
					query.lambda().eq(req.getGroupId() != null, UserGroupData::getGroupId, req.getGroupId())
							.orderByDesc(UserGroupData::getCreateTime, UserGroupData::getId);
					int count = userGroupDataService.count(query);
					return R.ok(count);
				default:
					return R.failed("未知筛选方式");
			}
		} catch (Exception e) {
			log.error("用户管理-用户群组数据统计-接口：{}", e.getMessage());
			return R.failed("接口异常，请联系管理员");
		}
	}



	@ApiOperation(value = "删除用户群组数据", notes = "删除用户群组数据")
	@SysLog("删除用户群组数据")
	@PreAuthorize("@pms.hasPermission('usergroup_data_delete')")
	@NoRepeatSubmit(lockTime = 3000)
	@RequestMapping("/delete")
	public R delete(@Valid @RequestBody UserGroupDataReq req){
		try {
			if (req.getId() == null){
				return R.failed("未获取到主键ID");
			}
			return userGroupDataService.delete(req.getId());
			//return R.ok(userGroupDataService.removeById(req.getId()));
		} catch (Throwable t) {
			return R.failed(t.getMessage());
		}

	}


	@ApiOperation(value = "批量删除用户群组数据", notes = "批量删除用户群组数据")
	@SysLog("批量删除用户群组数据")
	@PreAuthorize("@pms.hasPermission('usergroup_data_batchdelete')")
	@NoRepeatSubmit(lockTime = 3000)
	@RequestMapping("/batchDelete")
	public R batchDelete(@Valid @RequestBody UserGroupDataReq req){
		try {
			if (StringUtils.isBlank(req.getIds())) {
				return R.failed("请选择删除的内容");
			}
			List<String> list = Arrays.asList(req.getIds().split(","));
			return userGroupDataService.batchDelete(list);
			//return R.ok(userGroupDataService.removeByIds(list));
		}catch(Throwable t){
			return R.failed(t.getMessage());
		}
	}



	@ApiOperation(value = "新增用户群组数据", notes = "新增用户群组数据")
	@SysLog("新增用户群组数据")
	@PreAuthorize("@pms.hasPermission('usergroup_data_add')")
	@NoRepeatSubmit(lockTime = 3000)
	@RequestMapping("/add")
	public R add(@Valid @RequestBody UserGroupDataVo vo){
		Long groupId = vo.getGroupId();
		String lockKey = "user_group_data:upload:lock:" + groupId;
		final String lockValue = redisLock.tryLock(lockKey, 120000);
		try {
			if (StringUtils.isNotBlank(lockValue)) {
				vo.setId(null);
				return userGroupDataService.saveOrUpdateUserGroupData(vo);
			} else {
				return R.failed("该群组请勿同时操作");
			}

		} catch (Throwable t) {
			return R.failed(t.getMessage());
		}finally {
			redisLock.unlock(lockKey, lockValue);
		}
	}


	@ApiOperation(value = "修改用户群组数据", notes = "修改用户群组数据")
	@SysLog("修改用户群组数据")
	@PreAuthorize("@pms.hasPermission('usergroup_data_edit')")
	@NoRepeatSubmit(lockTime = 3000)
	@RequestMapping("/edit")
	public R edit(@Valid @RequestBody UserGroupDataVo vo){

		Long groupId = vo.getGroupId();
		String lockKey = "user_group_data:upload:lock:" + groupId;
		final String lockValue = redisLock.tryLock(lockKey, 120000);
		try {
			if (StringUtils.isNotBlank(lockValue)) {
				Long id = vo.getId();
				if(id == null){
					return R.failed("未获取到主键ID");
				}
				return userGroupDataService.saveOrUpdateUserGroupData(vo);
			} else {
				return R.failed("该群组请勿同时操作");
			}


		} catch (Throwable t) {
			return R.failed(t.getMessage());
		} finally {
			redisLock.unlock(lockKey, lockValue);
		}
	}


	@ApiOperation(value = "用户群组数据文件上传", notes = "用户群组数据文件上传")
	@SysLog("用户群组数据文件上传")
	@PreAuthorize("@pms.hasPermission('usergroup_data_upload')")
	@NoRepeatSubmit(lockTime = 3000)
	@RequestMapping("/upload")
	public R upload(UserGroupDataReq req){
		Long groupId = req.getGroupId();
		String lockKey = "user_group_data:upload:lock:" + groupId;
		final String lockValue = redisLock.tryLock(lockKey, 120000);
		try {
			if (StringUtils.isNotBlank(lockValue)) {
				if(groupId == null){
					return R.failed("请确认用户群组是否存在");
				}
				return userGroupDataService.uploadUserGroupData(req);

			}else{
				return R.failed("该群组请勿同时操作");
			}
		} catch (Throwable t) {
			return R.failed(t.getMessage());
		} finally {
			redisLock.unlock(lockKey, lockValue);
		}
	}


	@NoRepeatSubmit(lockTime = 3000)
	@RequestMapping("/device/list")
	public R devicebrandList(@RequestBody DeviceVo vo){

		/*List<Device> list = deviceService.list(Wrappers.<Device>query().lambda()
				.eq(vo.getPid() != null, Device::getPid, vo.getPid())
				.like(StringUtils.isNoneBlank(vo.getName()), Device::getName, vo.getName()).orderByAsc(Device::getId));*/

		List<Device> brandList = deviceService.list(Wrappers.<Device>query().lambda().eq(Device::getLevel, 1).orderByAsc(Device::getId));
		List<Device> modelList = deviceService.list(Wrappers.<Device>query().lambda().eq(Device::getLevel, 2).orderByAsc(Device::getId));
		digui(brandList.stream().collect(Collectors.toCollection(TreeSet::new)), modelList);
		return R.ok(brandList);
	}

	//递归获取自身及自身以下的节点
	private void digui(TreeSet<Device>  brands, List<Device> models) {
		TreeSet<Device> retList = new TreeSet<>();
		for (Device tags : brands) {
			//获取自身子节点
			retList = models.stream().filter(re -> re.getPid().compareTo(tags.getId()) == 0).collect(Collectors.toCollection(TreeSet::new));
			if (retList.size() > 0) {
				tags.setChildren(retList);
				//digui(retList, models); //循环调用自己
			}
		}
	}

	//递归获取自身及自身以下的节点
	private void digui_province(TreeSet<ProvinceCityInfo> provinces, List<ProvinceCityInfo> citys) {
		TreeSet<ProvinceCityInfo> retList = new TreeSet<>();
		for (ProvinceCityInfo tags : provinces) {
			//获取自身子节点
			retList = citys.stream().filter(re -> re.getPid().compareTo(tags.getId()) == 0).collect(Collectors.toCollection(TreeSet::new));
			if (retList.size() > 0) {
				tags.setChildren(retList);
				//digui_province(retList, citys); //循环调用自己
			}
		}
	}


	@NoRepeatSubmit(lockTime = 3000)
	@RequestMapping("/provinceCity/list")
	public R provinceCityList(@RequestBody ProvinceCityVo vo){

		List<ProvinceCityInfo> provinces = provinceCityInfoService.list(Wrappers.<ProvinceCityInfo>query().lambda()
				.eq(ProvinceCityInfo::getLevel, 1).orderByAsc(ProvinceCityInfo::getId));
		List<ProvinceCityInfo> citys = provinceCityInfoService.list(Wrappers.<ProvinceCityInfo>query().lambda()
				.eq(ProvinceCityInfo::getLevel, 2).orderByAsc(ProvinceCityInfo::getId));

		digui_province(provinces.stream().collect(Collectors.toCollection(TreeSet::new)), citys);

		return R.ok(provinces);
	}



	@RequestMapping("/device")
	public R device(HttpServletRequest request){
		//查询所有数据
		List<DeviceInfo> list = deviceInfoService.list(Wrappers.<DeviceInfo>query().lambda().select(DeviceInfo::getDevicebrand, DeviceInfo::getDevicemodel).orderByAsc(DeviceInfo::getId));
		//查询所有品牌数据-不重复
		List<String> devicebrandSet = list.stream().map(DeviceInfo::getDevicebrand).distinct().collect(Collectors.toList());


		List<Device> saveList = new ArrayList<>();
		for(String devicebrand : devicebrandSet){
			Device device = new Device();
			device.setPid(0L);
			device.setLevel(1);
			device.setName(devicebrand);
			device.setDeleted(0);
			device.setCreateId(1L);
			saveList.add(device);
		}
		//保存品牌数据
		deviceService.saveBatch(saveList);

		//查询品牌数据
		List<Device> deviceList = deviceService.list(Wrappers.<Device>query().lambda().select(Device::getId, Device::getName));

		for(Device device : deviceList){
			String devicebrand = device.getName();
			Long id = device.getId();
			//查询品牌下的机型数据
			List<DeviceInfo> modelList = deviceInfoService.list(Wrappers.<DeviceInfo>query().lambda().eq(DeviceInfo::getDevicebrand, devicebrand).select(DeviceInfo::getDevicebrand, DeviceInfo::getDevicemodel));
			for(DeviceInfo deviceInfo : modelList){
				Device entity = new Device();
				entity.setPid(id);
				entity.setLevel(2);
				entity.setName(deviceInfo.getDevicemodel());
				entity.setCreateId(1L);
				deviceService.saveOrUpdate(entity);
				//保存机型数据
			}
		}
		return R.ok();
	}



	@RequestMapping("/area")
	public R area(HttpServletRequest request){
		//查询所有数据
		List<AreaInfo> list = areaInfoService.list(Wrappers.<AreaInfo>query().lambda().select(AreaInfo::getProvince, AreaInfo::getCity).orderByAsc(AreaInfo::getId));
		//查询所有省份数据-不重复
		List<String> provinceSet = list.stream().map(AreaInfo::getProvince).distinct().collect(Collectors.toList());

		List<ProvinceCityInfo> saveList = new ArrayList<>();
		for(String province : provinceSet){
			ProvinceCityInfo entity = new ProvinceCityInfo();
			entity.setPid(0L);
			entity.setLevel(1);
			entity.setName(province);
			entity.setDeleted(0);
			entity.setCreateId(1L);
			saveList.add(entity);
		}
		//保存省份数据
		provinceCityInfoService.saveBatch(saveList);

		//查询省份数据
		List<ProvinceCityInfo> infoList = provinceCityInfoService.list(Wrappers.<ProvinceCityInfo>query().lambda().select(ProvinceCityInfo::getId, ProvinceCityInfo::getName).orderByAsc(ProvinceCityInfo::getId));

		for(ProvinceCityInfo info : infoList){
			String province = info.getName();
			Long id = info.getId();
			//查询省份下的市区数据
			List<AreaInfo> modelList = areaInfoService.list(Wrappers.<AreaInfo>query().lambda().eq(AreaInfo::getProvince, province).select(AreaInfo::getProvince, AreaInfo::getCity));
			for(AreaInfo item : modelList){
				ProvinceCityInfo entity = new ProvinceCityInfo();
				entity.setPid(id);
				entity.setLevel(2);
				entity.setName(item.getCity());
				entity.setCreateId(1L);
				provinceCityInfoService.saveOrUpdate(entity);
				//保存市区数据
			}
		}
		return R.ok();
	}

}
